import { getRealType } from './../Common'

/**
 * 重写vue-cookies
 */
const LvCookie = {
  /**
   * @method 设置和获取cookies
   * @param {string} key
   * @param {string} val
   * @param {number | date | string} expires 过期时间，默认86400s，1day
   * @param {string} path 设置url路径，控制可访问cookie的路径
   * @param {string} domain 设置域，该域下的主机都可以访问到cookie
   * @param {boolean} secure 若为true，不能使用http协议发送到服务器，只能用https
   */
  cookie(key ,val, expires = 86400, path, domain, secure) {

  	/**
  	 * # 先进行错误判断并抛出
     * 1. key必须有效
     * 2. key不能为关键字
     *    - (?:pattern)：获取pattern中的内容，性能比(pattern)好
     *    - ^pattern$：精确匹配pattern
     *    - i：不分大小写
     * 
  	 */

    if(!key) {// 1
      throw new Error('cookie名称无效，当前名称：' + key);
    } else if(/^(?:expires|max\-age|path|domain|secure)$/i.test(key)) {// 2
      throw new Error('cookie名称不能设置为[expires, max-age, path, domain, secure]，当前名称' + key);
    }

    if(key && !val) {// 取值
      return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), '$1')) || null;
    }


    let _expires = '; max-age=' + expires;
    if(key && val) {// 设值
      // 判断expires类型
      const type = getRealType(expires);
      switch(getRealType(expires)) {
        case 'number': {
          if(expires === Infinity || expires === -1) {// 无限大
            _expires = "; expires=Fri, 31 Dec 9999 23:59:59 GMT"
          } else {
            _expires = "; max-age=" + expires;
          }
          break;
        }
        case 'string': {
          if (/^(?:\d{1,}(?:y|m|d|h|min|s))$/i.test(expires)) {
            // 取时间数值
            const _expireTime = expires.replace(/^(\d{1,})(?:y|m|d|h|min|s)$/i, '$1');
            // 取时间类型
            switch (expires.replace(/^(?:\d{1,})(y|m|d|h|min|s)$/i, '$1').toLowerCase()) {
              // Frequency sorting
              case 'm':  { _expires = "; max-age=" + +_expireTime * 2592000; break; } // 60 * 60 * 24 * 30
              case 'd':  { _expires = "; max-age=" + +_expireTime * 86400; break; } // 60 * 60 * 24
              case 'h': { _expires = "; max-age=" + +_expireTime * 3600; break; } // 60 * 60
              case 'min': { _expires = "; max-age=" + +_expireTime * 60; break; } // 60
              case 's': { _expires = "; max-age=" + _expireTime; break; }
              case 'y': { _expires = "; max-age=" + +_expireTime * 31104000; break; } // 60 * 60 * 24 * 30 * 12
              default: new Error('时间参数无效，当前时间参数：' + expires);
            }
          } else {// date string
            _expires = "; expires=" + expires;
          }
          break;
        }
        case 'date': {
          _expires = "; expires=" + expires.toGMTString();
        }
        default: {}
      }
      document.cookie = encodeURIComponent(key) + "=" + encodeURIComponent(val) + _expires + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "") + (secure ? "; secure" : "");
    }
  },
  /**
   * @method 取出json格式的cookie值
   * @param {string}
   * @return {object}
   */
  cookieJson(key) {
    let val = decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), '$1')) || null;
    try { val = JSON.parse(JSON.stringify(val)); }
    catch(err) { throw new Error(err) }

    return val
  },
  /**
   * @method 删除cookie
   * @param {string} key 
   */
  remove(key, path, domain) {
    if(!key) {
      return false;
    }
    document.cookie = encodeURIComponent(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "");
    return true;
  },
  /**
   * @method 是否存在该键值
   * @param {string} key 
   */
  isKey(key) {
    // 匹配 "key=" 或 "; key="
    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  },
  /**
   * @method 返回所有键名
   */
  keys() {
    if(!document.cookie) return [];
    // 
    const _keys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (const idx in keys) {
      _keys[idx] = decodeURIComponent(_keys[idx]);
    }
    return _keys;
  }
}

export default LvCookie;